
#include "DeviceManager.h"
#include "DeviceInfo.h"

DeviceManager::DeviceManager() {
  _pAudioDevice = new AudioDevice();
}

DeviceManager::~DeviceManager() noexcept {
  clearDevice();
}

int32_t DeviceManager::addCameraDevice(int32_t devID, DeviceType deviceType) {
  auto pCameraDevice = new CameraDevice();
  pCameraDevice->devID = devID;
  pCameraDevice->devState = DeviceState_None;
  pCameraDevice->devType = deviceType;
  pCameraDevice->width = 0;
  pCameraDevice->height = 0;
  pCameraDevice->frameRate = 0;
  _VideoDeviceList.push_back(pCameraDevice);
}

int32_t DeviceManager::addIPCameraDevice(const char *streamUrl, bool isSoftDecode, DeviceType deviceType) {
  int32_t devID = _IPCameraBase;
  auto pIPCameraDevice = new IPCameraDevice();
  pIPCameraDevice->devID = devID;
  pIPCameraDevice->devState = DeviceState_None;
  pIPCameraDevice->devType = deviceType;
  pIPCameraDevice->isSoftDecode = isSoftDecode;
  strcpy(pIPCameraDevice->stStream, streamUrl);
  _VideoDeviceList.push_back(pIPCameraDevice);

  _IPCameraBase++;
  return devID;
}

void DeviceManager::deleteDevice(int32_t devID) {
  auto pDevice = findDeviceByID(devID);
  _VideoDeviceList.remove(pDevice);
  DELETE_PTR(pDevice)
}

void DeviceManager::clearDevice() {
  std::for_each(_VideoDeviceList.begin(), _VideoDeviceList.end(),
                [&](IDevice *pItem) {
                  if (pItem) {
                    DELETE_PTR(pItem)
                  }
                });
  _VideoDeviceList.clear();

  DELETE_PTR(_pAudioDevice)
}

void DeviceManager::modifyCameraDevice(int32_t width, int32_t height) {
  std::for_each(_VideoDeviceList.begin(), _VideoDeviceList.end(),
                [&](IDevice *pItem) {
                  if (pItem && pItem->devType == DeviceType_Camera) {
                    auto pCameraDevice = dynamic_cast<CameraDevice *>(pItem);
                    pCameraDevice->width = width;
                    pCameraDevice->height = height;
                  }
                });
}

void
DeviceManager::modifyCameraDevice(int32_t devID, int32_t width, int32_t height) {
  std::find_if(_VideoDeviceList.begin(), _VideoDeviceList.end(),
               [&](IDevice *pItem) {
                 if (pItem && pItem->devType == DeviceType_Camera && pItem->devID == devID) {
                   auto pCameraDevice = dynamic_cast<CameraDevice *>(pItem);
                   pCameraDevice->width = width;
                   pCameraDevice->height = height;
                   return true;
                 }
                 return false;
               });
}

void
DeviceManager::modifyAudioDevice(int32_t sampleRate, int32_t channelNum, int32_t sampleBitPer) {
  _pAudioDevice->samplesBitPer = sampleBitPer;
  _pAudioDevice->channelNum = channelNum;
  _pAudioDevice->sampleRate = sampleRate;
}

IDevice *DeviceManager::findDeviceByID(int32_t devID) {
  auto it = std::find_if(_VideoDeviceList.begin(), _VideoDeviceList.end(),
                         [&](IDevice *pItem) {
                           return pItem && pItem->devID == devID;
                         });

  if (it != _VideoDeviceList.end()) {
    return *it;
  }

  return nullptr;
}

std::list<IDevice *> DeviceManager::getDeviceList() {
  return _VideoDeviceList;
}

AudioDevice *DeviceManager::getAudioDevice() {
  if (_pAudioDevice && _pAudioDevice->sampleRate != 0 &&
      _pAudioDevice->samplesBitPer != 0 && _pAudioDevice->channelNum != 0) {
    return nullptr;
  }

  return _pAudioDevice;
}

int32_t DeviceManager::getCameraDeviceNum() {
  return std::count_if(_VideoDeviceList.begin(), _VideoDeviceList.end(),
                       [](IDevice *pItem) {
                         return pItem && pItem->devType == DeviceType_Camera;
                       });
}
